from rest_framework import serializers

from oauth.models import OAuthQQUser
from users.models import User
from django_redis import get_redis_connection
from itsdangerous import TimedJSONWebSignatureSerializer as TJS
from django.conf import settings
import re
from rest_framework_jwt.settings import api_settings


class OauthSerializer(serializers.ModelSerializer):
    # 显示指明模型类中没有的字段
    sms_code = serializers.CharField(max_length=6, min_length=6, write_only=True)
    access_token = serializers.CharField(write_only=True)
    token = serializers.CharField(read_only=True)
    mobile = serializers.CharField(max_length=11, write_only=True)

    class Meta:
        model = User
        fields = ('mobile', 'password', 'sms_code', 'access_token', 'id', 'username', 'token')
        read_only_fields = ('username',)
        extra_kwargs = {
            'password':
                {
                    'max_length': 20,
                    'min_length': 8,
                    'write_only': True
                },

        }

    # 验证手机号格式

    def validate_mobile(self, value):
        if not re.match(r'^1[3-9]\d{9}$', value):
            raise serializers.ValidationError('手机号格式不正确')

        return value

    def validate(self, attrs):
        # 短信验证
        # 1、建立redis连接
        conn = get_redis_connection('sms_code')
        # 2、获取真实的短信验证码
        real_sms_code = conn.get('sms_code_%s' % attrs['mobile'])
        # 3、判断是在有效期内
        if not real_sms_code:
            raise serializers.ValidationError('验证码失效')
        # 4、比对用户输入的和真实验证码
        if attrs['sms_code'] != real_sms_code.decode():
            raise serializers.ValidationError('验证码错误')

        # 解密access—token
        tjs = TJS(settings.SECRET_KEY, 300)
        try:
            data = tjs.loads(attrs['access_token'])  # {openid:asdasd}
        except:
            raise serializers.ValidationError('错误的access—token')

        # 提取openid值
        openid = data.get('open_id')
        if openid is None:
            raise serializers.ValidationError('access—token超过有效期')
        # openid 添加到attrs
        attrs['openid'] = openid

        # 用户判断
        try:
            user = User.objects.get(mobile=attrs['mobile'])
        except:
            # 用户不存在
            return attrs

        else:
            # 用户存在校验密码
            if not user.check_password(attrs['password']):
                raise serializers.ValidationError('密码错误')

            # attrs中添加user数据
            attrs['user'] = user
            return attrs

    def create(self, validated_data):

        # 判断用户是否注册
        user = validated_data.get('user')
        if user is None:
            user = User.objects.create_user(username=validated_data['mobile'], password=validated_data['password'],
                                            mobile=validated_data['mobile'])

        # 绑定openid
        OAuthQQUser.objects.create(user=user, openid=validated_data['openid'])

        # 生成JWT token值
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)

        # 在user对象中添加token属性
        user.token = token

        return user
